package by.semerikov.dao.factory.mysqlJdbc;

import java.sql.Connection; 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mysql.jdbc.PreparedStatement;

import by.semerikov.dao.Car;
import by.semerikov.dao.IDAO;
import by.semerikov.dao.Person;
import by.semerikov.data.Connector;
import by.semerikov.exceptions.BadObjectException;

public class CarDAO implements IDAO<Car> {
	
	private Connection con;
	PreparedStatement insertStatement;
	
	public CarDAO() throws SQLException {
		
		con = Connector.getConnection();
	}

	public CarDAO(Connection con) {
		this.con = con;
	}

	@Override
	public void create(Car object) throws BadObjectException {
		try {
			PreparedStatement preparedState = (PreparedStatement) con
					.prepareStatement("insert into transportsystem.cars (model,state,personal_id) values(?,?,?)");
			preparedState.setString(1, object.getModel());
			preparedState.setString(2, object.getState());
			if(object.getOwner() == null)
				throw new BadObjectException("Car should have a owner");
			preparedState.setInt(3, object.getOwner().getId());
			preparedState.executeUpdate();
		} catch (Exception e) {
			throw new BadObjectException("create" ,e );
		}
		
	}

	@Override
	public List<Car> read(Car object) throws BadObjectException {
		ArrayList<Car> newList = new ArrayList<Car>();
		try {
			PreparedStatement preparedState = doReadPreparedStatement(object,
					"SELECT * FROM transportsystem.cars ");
			ResultSet resultset = preparedState.executeQuery();
			while (resultset.next()) {
				PersonDAO pd = new PersonDAO();
				Person owner = pd.read(
						new Person( Integer.parseInt(resultset.getString("personal_id")),
								null, null, null, null, null)).get(0);
				if(owner == null)
					throw new BadObjectException("Owner is not found");
 				newList.add(new Car(Integer.parseInt(resultset
						.getString("id")), resultset.getString("model"),
						resultset.getString("state"), owner));
			}
			return newList;
		} catch (Exception e) {
			throw new BadObjectException(e);
		}
	}
	
	private PreparedStatement doReadPreparedStatement(Car object,
			String begin) throws SQLException {
		String newStr = begin;
		Map<String, Integer> map = new HashMap<String, Integer>();
		int number = 1;
		if (object.getId() != null) {
			newStr += "where  id = ?";
			map.put("id", number);
			number++;
		}
		if (object.getModel() != null) {
			if (number == 1)
				newStr += " where ";
			if (number != 1)
				newStr += " And ";
			newStr += " model Like ?";
			map.put("model", number);
			number++;
		}
		if (object.getState() != null) {
			if (number == 1)
				newStr += " where ";
			if (number != 1)
				newStr += " And ";
			newStr += " state Like ?";
			map.put("state", number);
			number++;
		}
		if (object.getOwner() != null) {
			if (number == 1)
				newStr += " where ";
			if (number != 1)
				newStr += " And ";
			newStr += " personal_id = ?";
			map.put("personal_id", number);
			number++;
		}
		PreparedStatement newPS = (PreparedStatement) con
				.prepareStatement(newStr);
		if (map.get("id") != null) {
			newPS.setInt(map.get("id"), object.getId());
		}
		if (map.get("model") != null) {
			newPS.setString(map.get("model"), "%" + object.getModel() + "%");
		}
		if (map.get("state") != null) {
			newPS.setString(map.get("state"), "%" + object.getState() + "%");
		}
		if (map.get("personal_id") != null) {

			PersonDAO pd = new PersonDAO();
			Person owner = pd.read(object.getOwner()).get(0);
			newPS.setInt(map.get("personal_id"), owner.getId()  );
		}
		return newPS;
	}

	@Override
	public void update(Car object) {
		try {
			PreparedStatement preparedState = (PreparedStatement) con
					.prepareStatement("UPDATE transportsystem.cars SET model=? , state=? , personal_id=?  WHERE id=?");
			preparedState.setString(1, object.getModel());
			preparedState.setString(2, object.getState());
			preparedState.setInt(3, object.getOwner().getId());
			preparedState.setInt(4, object.getId());
			preparedState.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	@Override
	public void delete(Car object) {
		try {
			PreparedStatement preparedState = doReadPreparedStatement(object,
					"DELETE FROM transportsystem.cars ");
			preparedState.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}
